<?php
if (!defined('ABSPATH')) {
    exit();
}
if (!class_exists('CMC_api_data')) {
    class CMC_api_data
    {

        /**
         * CMC_MAIN_TABLE_LIST  used for main table coins list Transient name.
         * ONE_TO_2500_COINS used for top 2500 coins transient time
         * TWENTY_FIVE_TO_5000_COINS used for  2500-5000 coins transient time
         */
        const CMC_MAIN_TABLE_LIST = 'cmc-saved-coindata-batch';
        const ONE_TO_2500_COINS = 10 * MINUTE_IN_SECONDS;
        const TWENTY_FIVE_TO_5000_COINS = 3 * HOUR_IN_SECONDS;

        /**
         * CMC_MAIN_TABLE_WEEKLY used for main table coins 7 day weekly chart data Transient name.
         * WEEKLY_1_2500_COINS used for top 2500 coins weekly data transient time
         * WEEKLY_2500_5000_COINS used for 2500-5000 coins weekly data transient time
         */
        const CCPWP_UNAVILABLE_DATA = 'ccpwp-unavailable-coins';
        const CCPWP_UNAVILABLE_DATA_CMC = 'ccpwp-unavailable-coins-cmc';

        const CCPWP_REFRESH_COINS = 'ccpwp-ua-coins-refresh';
        const CMC_MAIN_TABLE_WEEKLY = 'cmc-saved-weeklydata-batch';
        const WEEKLY_1_2500_COINS = HOUR_IN_SECONDS * 12;
        const WEEKLY_2500_5000_COINS = DAY_IN_SECONDS;

        /**
         * CMC_EXTRA_DATA used for coins extra data transient name.
         */
        const CMC_EXTRA_DATA = 'cmc-saved-coindata-extras-batch';
        const CMC_EXTRA_DATA_TRANSIENT = MONTH_IN_SECONDS;

        /**
         * CMC_COINS_DESCRIPTION used for coins description transient name.
         */
        const CMC_COINS_DESCRIPTION = 'cmc-saved-desc-batch';
        const CMC_COINS_DESCRIPTION_TRANSIENT = MONTH_IN_SECONDS;

        /**
         * CMC_USD_CONVERSION used for coins fiat conversion transient name.
         */
        const CMC_USD_CONVERSION = 'cmc_usd_conversions';
        const CMC_USD_CONVERSION_TRANSIENT = 3 * HOUR_IN_SECONDS;

        /**
         * This transient used for coins single page chart, historical data.
         * HISTORICAL_24H used for coins single page 24 hour chart  data transient time.
         * HISTORICAL_365D used for coins single page 365 day chart, historical table data transient time.
         */
        const HISTORICAL_24H = 2 * HOUR_IN_SECONDS;
        const HISTORICAL_365D = 6 * HOUR_IN_SECONDS;

        /**
         * CMC_API_LIMIT Transient created when daily API limit reached.
         */
        const CMC_API_LIMIT = 'cmc_api_limit';
        const CMC_API_LIMIT_TIME = 1 * HOUR_IN_SECONDS;


        /**
         * COINGECKO_API_ENDPOINT
         *
         * Holds the URL of the coingecko API.
         *
         * @access public
         *
         */
        const COINGECKO_API_ENDPOINT = 'https://api.coingecko.com/api/v3/';
        /**
         * COINMARKETCAP_API_ENDPOINT
         *
         * Holds the URL of the coins data API.
         *
         * @access public
         *
         */
        const COINMARKETCAP_API_ENDPOINT = 'https://pro-api.coinmarketcap.com/';

        /**
         * COINPAPRIKA_API_ENDPOINT
         *
         * Holds the URL of the coinpaprika API.
         *
         * @access public
         *
         */
        const COINPAPRIKA_API_ENDPOINT = 'https://api.coinpaprika.com/v1/';

        /**
         * OPENEXCHANGERATE_API_ENDPOINT
         *
         * Holds the URL of the openexchangerates API.
         *
         * @access public
         *
         */

        const OPENEXCHANGERATE_API_ENDPOINT = 'https://openexchangerates.org/api/latest.json?app_id=';

        public function __construct()
        {
        }

        // Function to get the CoinGecko API key
        public static function get_coingecko_api_key_cmc() {
            $api_option = get_option("openexchange-api-settings");
            $api_key =(isset($api_option['coingecko_api'])) ? $api_option['coingecko_api'] : ""; // Default API key
            // Apply filter to allow changing the API key
            $api_key = apply_filters('coingecko_api_key', $api_key);
            return $api_key;
        }

        //Api selection function
        public static function cmc_get_selected_api_data($page = 1)
        {

            $api_option = get_option("openexchange-api-settings");
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";
            if ($api_type == "coingecko") {
                return self::save_cmc_coins_data($page);
            } else if ($api_type == "coinmarketcap") {
                return self::cmc_get_cmc_api_data($page);
            } else if ($api_type == "both_coingecko") {
                if ((self::get_coingecko_api_key_cmc()) !== NULL) {
                    return self::save_cmc_coins_data($page);
                } else if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_get_cmc_api_data($page);
                }

            } else if ($api_type == "both_coinmarketcap") {
                if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_get_cmc_api_data($page);

                } else if ((self::get_coingecko_api_key_cmc()) !== NULL) {
                    return self::save_cmc_coins_data($page);
                }
            }
        }
        //API selection for unavailable coins
        public static function cmc_get_selected_api_ua_data($coin_ids = array(), $single = false, $gl = false)
        {
            $api_option = get_option("openexchange-api-settings");
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";
            if ($api_type == "coingecko") {
                return self::cmc_update_unavailable_coins_data($coin_ids, $single, $gl);
            } else if ($api_type == "coinmarketcap") {
                return self::cmc_update_unavailable_coins_data_cmc($coin_ids, $single, $gl);
            } else if ($api_type == "both_coingecko") {
                if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::cmc_update_unavailable_coins_data($coin_ids, $single, $gl);
                } else if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_update_unavailable_coins_data_cmc($coin_ids, $single, $gl);
                }

            } else if ($api_type == "both_coinmarketcap") {
                if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_update_unavailable_coins_data_cmc($coin_ids, $single, $gl);
                } else if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::cmc_update_unavailable_coins_data($coin_ids, $single, $gl);
                }

            }

        }

        //Api selection function for social data
        public static function cmc_select_social_data_api($coin_id)
        {
            $api_option = get_option("openexchange-api-settings");
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";
            if ($api_type == "coingecko") {
                return self::save_coins_social_info($coin_id);
            } else if ($api_type == "coinmarketcap") {
                return self::cmc_save_coins_social_info($coin_id);
            } else if ($api_type == "both_coingecko") {
                if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::save_coins_social_info($coin_id);
                } else if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_save_coins_social_info($coin_id);
                }

            } else if ($api_type == "both_coinmarketcap") {
                if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_save_coins_social_info($coin_id);

                } else if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::save_coins_social_info($coin_id);

                }

            }

        }
        //Api selection function for global data
        public static function cmc_select_global_data_api()
        {
            $api_option = get_option("openexchange-api-settings");
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";
            if ($api_type == "coingecko") {
                return self::cmc_store_global_data();
            } else if ($api_type == "coinmarketcap") {
                return self::cmc_store_global_data_from_cmc_api();
            } else if ($api_type == "both_coingecko") {
                if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::cmc_store_global_data();
                } else if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_store_global_data_from_cmc_api();
                }

            } else if ($api_type == "both_coinmarketcap") {
                if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_store_global_data_from_cmc_api();

                } else if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::cmc_store_global_data();

                }

            }

        }
        //Api selection function for global data
        public static function cmc_select_historical_data_api($coin_id, $day)
        {
            $api_option = get_option("openexchange-api-settings");
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";
            if ($api_type == "coingecko") {
                return self::cmc_historical_coins_arr($coin_id, $day);
            } else if ($api_type == "coinmarketcap") {
                return self::cmc_historical_coins_from_cmc_api($coin_id, $day);
            } else if ($api_type == "both_coingecko") {
                if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::cmc_historical_coins_arr($coin_id, $day);
                } else if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_historical_coins_from_cmc_api($coin_id, $day);
                }

            } else if ($api_type == "both_coinmarketcap") {
                if (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) {
                    return self::cmc_historical_coins_from_cmc_api($coin_id, $day);

                } else if (NULL !== (self::get_coingecko_api_key_cmc())) {
                    return self::cmc_historical_coins_arr($coin_id, $day);

                }

            }

        }

        /*
        |-----------------------------------------------------------
        | Fetching data through CoinGecko API and save in database
        |-----------------------------------------------------------
         */
        public static function save_cmc_coins_data($page = 1)
        {
            $data_cache_name = self::CMC_MAIN_TABLE_LIST . $page;
            $ua_coins_name = self::CCPWP_UNAVILABLE_DATA;
        
            $ua_refresh_time = get_transient(self::CCPWP_REFRESH_COINS);
            $ua_coins_cache = get_option($ua_coins_name);
            $cache = get_transient($data_cache_name);
        
            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_key = isset($api_option['coingecko_api']) ? sanitize_text_field($api_option['coingecko_api']) : "";
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
        
            // Do not proceed further if required settings are missing
            if (!cmc_check_required_settings()) {
                return;
            }
        
            // Avoid updating database if cache exists
            if (false !== $cache) {
                return;
            }
        
            // API URL
            $api_url = cmc_get_api_end_point() . 'coins/markets?vs_currency=usd&order=market_cap_desc&per_page=250&page=' . $page . '&sparkline=true&price_change_percentage=24h%2C7d%2C30d%2C1y&' . cmc_get_api_key_end_point() . '=' . $coingecko_api_key;
        
            // Fetch data from the API
            $request = wp_remote_get($api_url, array('timeout' => 300, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early on error
            }
        
            $body = wp_remote_retrieve_body($request);
            $coins = json_decode($body);
        
            if (!is_array($coins)) {
                return false; // Bail if API response is not an array
            }
        
            if (cmc_check_api_errors($coins)) {
                return self::save_cmc_coins_data_backup();
            }
        
            $response = array();
            $coin_data = array();
            $db_coins = array();
            $coinid_list = array();
        
            if (isset($coins) && is_array($coins)) {
                cmc_track_coingecko_api_hit();
        
                foreach ($coins as $coin) {
        
                    // Ensure $coin is an object and properties exist
                    if (!is_object($coin)) {
                        continue;
                    }
        
                    // Skip coins with emoji in name, symbol, or coin_id
                    if (self::contains_emoji($coin->name ?? '') || self::contains_emoji($coin->symbol ?? '') || self::contains_emoji($coin->id ?? '')) {
                        continue;
                    }
        
                    $response['coin_id'] = sanitize_text_field($coin->id ?? '');
                    $response['name'] = sanitize_text_field($coin->name ?? '');
                    $response['symbol'] = strtoupper(sanitize_text_field($coin->symbol ?? ''));
                    $response['price'] = cmc_set_default_if_empty($coin->current_price);
                    $response['percent_change_24h'] = cmc_set_default_if_empty($coin->price_change_percentage_24h);
                    $response['percent_change_1y'] = cmc_set_default_if_empty($coin->price_change_percentage_1y_in_currency );
                    $response['percent_change_30d'] = cmc_set_default_if_empty($coin->price_change_percentage_30d_in_currency);
                    $response['percent_change_7d'] = cmc_set_default_if_empty($coin->price_change_percentage_7d_in_currency);
                    $response['market_cap'] = cmc_set_default_if_empty($coin->market_cap);
                    $response['total_volume'] = cmc_set_default_if_empty($coin->total_volume);
                    $response['circulating_supply'] = cmc_set_default_if_empty($coin->circulating_supply);
                    $response['high_24h'] = cmc_set_default_if_empty($coin->high_24h);
                    $response['low_24h'] = cmc_set_default_if_empty($coin->low_24h);
                    $response['ath'] = cmc_set_default_if_empty($coin->ath);
                    $response['ath_change_percentage'] = cmc_set_default_if_empty($coin->ath_change_percentage);
                    $response['ath_date'] = sanitize_text_field($coin->ath_date ?? '');
        
                    $charts = array();
                    if (!empty($coin->sparkline_in_7d->price) && is_array($coin->sparkline_in_7d->price)) {
                        $x = 0;
                        foreach ($coin->sparkline_in_7d->price as $chart) {
                            if ($x % 6 === 0) {
                                $charts[] = cmc_formatNumberWithDynamicDecimals($chart, false);
                            }
                            $x++;
                        }
                    }
                    $response['weekly_price_data'] = !empty($charts) ? serialize($charts) : null;
                    $response['logo'] = substr(sanitize_url($coin->image ?? ''), strpos($coin->image ?? '', "images") + 7);
        
                    $coin_data[] = $response;
                    $db_coins[] = sanitize_text_field($coin->id ?? '');
                    $coinid_list[] = sanitize_text_field($coin->id ?? '');
        
                    // Save data in chunks of 50 to avoid memory issues
                    if (count($coin_data) >= 50) {
                        self::save_coin_data($coin_data);
                        $coin_data = array(); // Reset array for next chunk
                    }
                }
        
                // Save any remaining data that was not saved in the last chunk
                if (!empty($coin_data)) {
                    self::save_coin_data($coin_data);
                }
        
                if ($page == 1) {
                    update_option('ccpwp-available-coins', $db_coins, true);
                }
                set_transient($data_cache_name, date('H:i:s'), $coingecko_api_cache_time * MINUTE_IN_SECONDS);
            }
        
            // Fetch coins other than the 250 default coins
            if (false === $ua_refresh_time) {
                self::cmc_update_unavailable_coins_data($ua_coins_cache);
            }
        }
        /**
         * Save coin data to the database.
         *
         * @param array $coin_data The coin data to save.
         */
        private static function save_coin_data($coin_data)
        {
            $DB = new CMC_Coins();
            $DB->cmc_insert($coin_data);
        }



        /*
        |-----------------------------------------------------------
        | Fetching data through Coinmarketcap API and save in database
        |-----------------------------------------------------------
         */
        public static function cmc_get_cmc_api_data($page = 1)
        {
            $api_option = get_option("openexchange-api-settings");

            $data_cache_name = self::CMC_MAIN_TABLE_LIST . $page;
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";

            $ua_coins_name = ($api_type == "both_coinmarketcap" || $api_type == "coinmarketcap") ? self::CCPWP_UNAVILABLE_DATA_CMC : self::CCPWP_UNAVILABLE_DATA;

            $ua_refresh_time = get_transient(self::CCPWP_REFRESH_COINS);
            $ua_coins_cache = get_option($ua_coins_name);

            $cache = get_transient($data_cache_name);
            $numberoftokens = ($page == 1) ? $page : ($page - 1) * 200;

            // Avoid updating database if cache exist or CMC is active
            if (false != $cache) {
                return;
            }

            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            $api_key = (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) ? $api_option['coinmarketcap_api'] : '';
            $coins = array();
            $request = wp_remote_get(self::COINMARKETCAP_API_ENDPOINT . 'v1/cryptocurrency/listings/latest?start=' . $numberoftokens . '&limit=200&CMC_PRO_API_KEY=' . $api_key, array('timeout' => 120, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $coins = json_decode($body, true);

            $response = array();
            $coin_data = array();
            $db_coins = array();
            $coinid_list = array();
            if (isset($coins['data']) && $coins['data'] != "" && is_array($coins['data'])) {
                foreach ($coins['data'] as $coin) {

                    // Skip coins with emoji in name, symbol, or coin_id
                    if (is_array($coin)) {
                        if (self::contains_emoji($coin['name']) || self::contains_emoji($coin['symbol']) || self::contains_emoji($coin['id'])) {
                            continue;
                        }
                    } else {
                        if ( self::contains_emoji($coin->name) || self::contains_emoji($coin->symbol) ||  self::contains_emoji($coin->id)) {
                            continue;
                             }
                    }
                    

                    //if (isset($coin['id']) && cmc_coin_array($coin['id'])) {
                    $cp = cmc_set_default_if_empty($coin['quote']['USD']['price'], 0.00);
                    $coin_id = cmc_coin_array_ids($coin['slug']);
                    $response['coin_id'] = $coin_id;
                    // $response['rank'] = $coin['rank'];
                    $response['name'] = $coin['name'];
                    $response['symbol'] = strtoupper($coin['symbol']);
                    $response['price'] = $cp;
                    $response['percent_change_24h'] = cmc_set_default_if_empty($coin['quote']['USD']['percent_change_24h']);
                    $response['percent_change_7d'] = cmc_set_default_if_empty($coin['quote']['USD']['percent_change_7d']);
                    $response['percent_change_30d'] = cmc_set_default_if_empty($coin['quote']['USD']['percent_change_30d']);
                    //$response['percent_change_1y'] = cmc_set_default_if_empty($coin['quote']['USD']['percent_change_1y']);
                    $response['high_24h'] = $cp * 1.02;
                    $response['low_24h'] = $cp * 0.98;
                    $response['market_cap'] = cmc_set_default_if_empty($coin['quote']['USD']['market_cap'], 0);
                    $response['total_volume'] = cmc_set_default_if_empty($coin['quote']['USD']['volume_24h']);
                    $response['circulating_supply'] = cmc_set_default_if_empty($coin['circulating_supply']);
                    //$response['ath'] = cmc_set_default_if_empty($coin['quote']['USD']['ath_price'], 0);
                    //$response['ath_date'] = 0;
                    // $response['ath_change_percentage'] = cmc_set_default_if_empty($coin['quote']['USD']['percent_from_price_ath'], 0);
                    $extradata = array('cmc_id' => $coin['id'], 'rank' => $coin['cmc_rank']);
                    $response['extradata'] = maybe_serialize($extradata);
                    $response['last_updated'] = gmdate('Y-m-d h:i:s');
                    $coin_data[] = $response;
                    $db_coins[] = $coin_id;

                    // Save data in chunks of 50 to avoid memory issues
                    if (count($coin_data) >= 50) {
                        self::save_coin_data($coin_data);
                        $coin_data = array(); // Reset array for next chunk
                    }

                }
              
            // Save any remaining data that was not saved in the last chunk
            if (!empty($coin_data)) {
                self::save_coin_data($coin_data);
            }



                if ($page == 1) {
                    update_option('ccpwp-available-coins', $db_coins, true);
                }
                // save all the coin id's udated through API by default
                //update_option( 'ccpw-default-coins', $default_coins , $coinid_list );
                set_transient($data_cache_name, date('H:s:i'), $coingecko_api_cache_time * MINUTE_IN_SECONDS);

            }

            // fetch other than 250 default coins
            if (false == $ua_refresh_time) {
                self::cmc_update_unavailable_coins_data($ua_coins_cache);
            }

        } // end of ccpwp_get_coin_gecko_data()

/*
|-----------------------------------------------------------
| Fetching data through Coinpaprika API and save in database
|-----------------------------------------------------------
 */
        public static function save_cmc_coins_data_backup($page = 1)
        {

            $data_cache_name = self::CMC_MAIN_TABLE_LIST . $page;

            $cache = get_transient($data_cache_name);

            // Avoid updating database if cache exist or CMC is active
            if (false != $cache) {
                return;
            }
            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            $coins = array();
            $request = wp_remote_get($api_url = self::COINPAPRIKA_API_ENDPOINT . 'tickers', array('timeout' => 300, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $coins = json_decode($body, true);

            $response = array();
            $coin_data = array();
            $db_coins = array();
            $coinid_list = array();
            if (isset($coins) && $coins != "" && is_array($coins)) {
                foreach ($coins as $coin) {
                    // Skip coins with emoji in name, symbol, or coin_id
                    if (is_array($coin)) {
                        if (self::contains_emoji($coin['name']) || self::contains_emoji($coin['symbol']) || self::contains_emoji($coin['id'])) {
                            continue;
                        }
                    } else {
                        if ( self::contains_emoji($coin->name) || self::contains_emoji($coin->symbol) ||  self::contains_emoji($coin->id)) {
                            continue;
                             }
                    }

                    
                    
                    if (isset($coin['id']) && cmc_coin_array($coin['id'])) {
                        $cp = cmc_set_default_if_empty($coin['quotes']['USD']['price'], 0.00);
                        $response['coin_id'] = cmc_coin_array($coin['id']);
                        // $response['rank'] = $coin['rank'];
                        $response['name'] = $coin['name'];
                        $response['symbol'] = strtoupper($coin['symbol']);
                        $response['price'] = $cp;
                        $response['percent_change_24h'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_24h']);
                        $response['percent_change_7d'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_7d']);
                        $response['percent_change_30d'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_30d']);
                        $response['percent_change_1y'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_1y']);
                        $response['high_24h'] = $cp * 1.02;
                        $response['low_24h'] = $cp * 0.98;
                        $response['market_cap'] = cmc_set_default_if_empty($coin['quotes']['USD']['market_cap'], 0);
                        $response['total_volume'] = cmc_set_default_if_empty($coin['quotes']['USD']['volume_24h']);
                        $response['circulating_supply'] = cmc_set_default_if_empty($coin['circulating_supply']);
                        $response['ath'] = cmc_set_default_if_empty($coin['quotes']['USD']['ath_price'], 0);
                        $response['ath_date'] = cmc_set_default_if_empty($coin['quotes']['USD']['ath_date']);
                        $response['ath_change_percentage'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_from_price_ath'], 0);
                        $response['last_updated'] = gmdate('Y-m-d h:i:s');

                        $coin_data[] = $response;
                    }

                }
                $cmcDB = new CMC_Coins();

                $parts = null;
                $previous = 0;
                for ($i = 0; $i < 6; $i++) {
                    $now = $previous;
                    $parts = array_slice($coin_data, $now, $previous + 600);
                    $parts = objectToArray($parts);
                    $savedd = $cmcDB->cmc_insert($parts);
                    $previous += 600;
                }

                // save all the coin id's udated through API by default
                //update_option( 'ccpw-default-coins', $default_coins , $coinid_list );
                set_transient($data_cache_name, date('H:s:i'), $coingecko_api_cache_time * MINUTE_IN_SECONDS);

            }

            //sleep($delay);
        } // end of ccpwp_get_coin_gecko_data()

/*
|-----------------------------------------------------------
| Fetching data through CoinGecko API and save in database
|-----------------------------------------------------------
 */
        public static function cmc_update_unavailable_coins_data($coin_ids = array(), $single = false, $gl = false)
        {
            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_key = self::get_coingecko_api_key_cmc();
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            // Do not proceed further if
            if (!cmc_check_required_settings()) {
                return;
            }

            $ua_coins_name = self::CCPWP_UNAVILABLE_DATA;
            $ua_refresh_time = self::CCPWP_REFRESH_COINS;
            $ua_coins_cache = get_option($ua_coins_name);

            if (is_array($coin_ids) && empty($coin_ids) || $coin_ids == '') {
                return false; // terminate further exectuition if no ids has passed in the argument;
            }
            $required_coins = urlencode(implode(',', $coin_ids));
            $coins = array();
            $api_url = cmc_get_api_end_point() . 'coins/markets?ids=' . $required_coins . '&vs_currency=usd&order=market_cap_desc&sparkline=true&price_change_percentage=24h%2C7d%2C30d%2C1y&' . cmc_get_api_key_end_point() . '=' . $coingecko_api_key;
            //$api_url = 'https://api.coingecko.com/api/v3/coins/markets?ids='.$required_coins.'&vs_currency=usd&order=market_cap_desc&sparkline=true&price_change_percentage=24h%2C7d%2C30d%2C1y';
            $request = wp_remote_get($api_url, array('timeout' => 300, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $coins = json_decode($body);
            if (cmc_check_api_errors($coins)) {
                return self::cmc_update_unavailable_coins_data_backup($coin_ids = array(), $single = false);
            }

            $response = array();
            $coin_data = array();
            $db_coins = array();

            if (isset($coins) && $coins != "" && is_array($coins)) {
                cmc_track_coingecko_api_hit();
                foreach ($coins as $coin) {
                    $response['coin_id'] = $coin->id;
                    //$response['rank'] = $coin->market_cap_rank;
                    $response['name'] = $coin->name;
                    $response['symbol'] = strtoupper($coin->symbol);
                    $response['price'] = cmc_set_default_if_empty($coin->current_price, 0.00);
                    $response['percent_change_24h'] = cmc_set_default_if_empty($coin->price_change_percentage_24h, 0);
                    $response['market_cap'] = cmc_set_default_if_empty($coin->market_cap, 0);
                    $response['total_volume'] = cmc_set_default_if_empty($coin->total_volume);
                    $response['circulating_supply'] = cmc_set_default_if_empty($coin->circulating_supply);
                    $response['high_24h'] = cmc_set_default_if_empty($coin->high_24h, 0);
                    $response['low_24h'] = cmc_set_default_if_empty($coin->low_24h, 0);
                    $response['ath'] = cmc_set_default_if_empty($coin->ath, 0);
                    $response['ath_change_percentage'] = cmc_set_default_if_empty($coin->ath_change_percentage, 0);
                    $response['ath_date'] = cmc_set_default_if_empty($coin->ath_date);

                    $charts = array();
                    if (!empty($coin->sparkline_in_7d->price)) {
                        $x = 0;
                        foreach ($coin->sparkline_in_7d->price as $chart) {
                            if ($x % 6 === 0) {
                                $charts[] = cmc_formatNumberWithDynamicDecimals($chart, false);

                            }
                            $x++;
                        }
                    }
                    $response['weekly_price_data'] = !empty($charts) ? serialize($charts) : null;

                    $response['logo'] = substr($coin->image, strpos($coin->image, "images") + 7);
                    $coin_data[] = $response;
                    $db_coins[] = $coin->id;
                }
                $DB = new CMC_Coins();
                // $DB->create_table();
                $DB->cmc_insert($coin_data);
                if ($gl == true) {
                    return;
                }
                if ($single == true) {
                    set_transient('cmc_single_coin' . $required_coins, $coin_data, 10 * MINUTE_IN_SECONDS);
                    return $coin_data;
                }
                if (is_array($db_coins) && !empty($db_coins) && $single == false) {

                    $db_coins = $ua_coins_cache == '' ? $db_coins : array_merge($ua_coins_cache, $db_coins);
                    $db_coins = array_unique($db_coins);
                    update_option($ua_coins_name, $db_coins, true);
                    set_transient($ua_refresh_time, date('H:s:i'), $coingecko_api_cache_time * MINUTE_IN_SECONDS);
                }

            }

        } // end of ccpwp_update_unavailable_coins_data()

        /*
        |-----------------------------------------------------------
        | Fetching data through Coinmarketcap API and save in database
        |-----------------------------------------------------------
         */
        public static function cmc_update_unavailable_coins_data_cmc($coin_ids = array(), $single = false, $gl = false)
        {

            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            $api_key = (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) ? $api_option['coinmarketcap_api'] : '';
            $api_type = (isset($api_option['select_api'])) ? $api_option['select_api'] : "coingecko";

            // Do not proceed further if
            if (!cmc_check_required_settings()) {
                return;
            }

            $ua_coins_name = ($api_type == "both_coinmarketcap" || $api_type == "coinmarketcap") ? self::CCPWP_UNAVILABLE_DATA_CMC : self::CCPWP_UNAVILABLE_DATA;
            $ua_refresh_time = self::CCPWP_REFRESH_COINS;
            $ua_coins_cache = get_option($ua_coins_name);

            if (is_array($coin_ids) && empty($coin_ids) || $coin_ids == '') {
                return false; // terminate further exectuition if no ids has passed in the argument;
            }
            $required_coins = urlencode(implode(',', $coin_ids));
            $common_id = (($api_type == "coinmarketcap" || $api_type == "both_coinmarketcap") && $single == true) ? cmc_coin_array_ids($required_coins, true) : $required_coins;
            $coins = array();

            $request = wp_remote_get(self::COINMARKETCAP_API_ENDPOINT . 'v3/cryptocurrency/quotes/latest?slug=' . $common_id . '&CMC_PRO_API_KEY=' . $api_key, array('timeout' => 120, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $coins = json_decode($body, true);

            $response = array();

            $db_coins = array();
            $coinid_list = array();

            if (isset($coins['data']) && $coins['data'] != "" && is_array($coins['data'])) {
                cmc_track_coingecko_api_hit();

                foreach ($coins['data'] as $coin) {
                    $usd_quote = isset($coin['quote']['USD']) ? $coin['quote']['USD'] : array();
                    $cp = cmc_set_default_if_empty(isset($usd_quote['price']) ? $usd_quote['price'] : null, 0.00);
                    $coin_id = cmc_coin_array_ids($coin['slug']);
                    $response['coin_id'] = $coin_id;
                    // $response['rank'] = $coin['rank'];
                    $response['name'] = $coin['name'];
                    $response['symbol'] = strtoupper($coin['symbol']);
                    $response['price'] = $cp;
                    $response['percent_change_24h'] = cmc_set_default_if_empty(isset($usd_quote['percent_change_24h']) ? $usd_quote['percent_change_24h'] : null);
                    $response['percent_change_7d'] = cmc_set_default_if_empty(isset($usd_quote['percent_change_7d']) ? $usd_quote['percent_change_7d'] : null);
                    $response['percent_change_30d'] = cmc_set_default_if_empty(isset($usd_quote['percent_change_30d']) ? $usd_quote['percent_change_30d'] : null);
                    //$response['percent_change_1y'] = cmc_set_default_if_empty(isset($usd_quote['percent_change_1y']) ? $usd_quote['percent_change_1y'] : null);
                    $response['high_24h'] = $cp * 1.02;
                    $response['low_24h'] = $cp * 0.98;
                    $response['market_cap'] = cmc_set_default_if_empty(isset($usd_quote['market_cap']) ? $usd_quote['market_cap'] : null, 0);
                    $response['total_volume'] = cmc_set_default_if_empty(isset($usd_quote['volume_24h']) ? $usd_quote['volume_24h'] : null);
                    $response['circulating_supply'] = cmc_set_default_if_empty($coin['circulating_supply']);
                    //$response['ath'] = cmc_set_default_if_empty(isset($usd_quote['ath_price']) ? $usd_quote['ath_price'] : null, 0);
                    //  $response['ath_date'] = cmc_set_default_if_empty(isset($usd_quote['ath_date']) ? $usd_quote['ath_date'] : null);
                    // $response['ath_change_percentage'] = cmc_set_default_if_empty(isset($usd_quote['percent_from_price_ath']) ? $usd_quote['percent_from_price_ath'] : null, 0);
                    $extradata = array('cmc_id' => $coin['id'], 'rank' => $coin['cmc_rank']);
                    $response['extradata'] = maybe_serialize($extradata);
                    $response['last_updated'] = gmdate('Y-m-d h:i:s');
                    $coin_data[] = $response;
                    $db_coins[] = $coin_id;
                }

                $DB = new CMC_Coins();
                // $DB->create_table();
                $DB->cmc_insert($coin_data);
                if ($gl == true) {
                    return;
                }
                if ($single == true) {
                    set_transient('cmc_single_coin' . $required_coins, $coin_data, 10 * MINUTE_IN_SECONDS);
                    return $coin_data;
                }
                if (is_array($db_coins) && !empty($db_coins) && $single == false) {

                    $db_coins = $ua_coins_cache == '' ? $db_coins : array_merge($ua_coins_cache, $db_coins);
                    $db_coins = array_unique($db_coins);
                    update_option($ua_coins_name, $db_coins, true);
                    set_transient($ua_refresh_time, date('H:s:i'), $coingecko_api_cache_time * MINUTE_IN_SECONDS);
                }

            }

        } // end of ccpwp_update_unavailable_coins_data()

        /*
        |-----------------------------------------------------------
        | Fetching data through CoinGecko API and save in database
        |-----------------------------------------------------------
         */
        public static function cmc_update_unavailable_coins_data_backup($coin_ids = array(), $single = false)
        {

            $ua_coins_name = self::CCPWP_UNAVILABLE_DATA;
            $ua_refresh_time = self::CCPWP_REFRESH_COINS;
            $ua_coins_cache = get_option($ua_coins_name);

            if (!is_array($coin_ids) && empty($coin_ids) || $coin_ids == '') {
                return false; // terminate further exectuition if no ids has passed in the argument;
            }
            $coin_data = array();
            foreach ($coin_ids as $key => $coin_id) {
                $required_coins = $coin_id;
                if (!cmc_coin_array($required_coins, true)) {
                    return;
                }
                $api_option = get_option("openexchange-api-settings");
                $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
                $coin = array();
                $request = wp_remote_get($api_url = self::COINPAPRIKA_API_ENDPOINT . 'tickers/' . cmc_coin_array($required_coins, true), array('timeout' => 300, 'sslverify' => true));
                if (is_wp_error($request)) {
                    return false; // Bail early
                }

                $body = wp_remote_retrieve_body($request);
                $coin = json_decode($body, true);

                $response = array();

                $db_coins = array();
                $coinid_list = array();
                if (isset($coin) && $coin != "" && is_array($coin)) {

                    $cp = cmc_set_default_if_empty($coin['quotes']['USD']['price'], 0.00);
                    $response['coin_id'] = cmc_coin_array($coin['id']);
                    // $response['rank'] = $coin['rank'];
                    $response['name'] = $coin['name'];
                    $response['symbol'] = strtoupper($coin['symbol']);
                    $response['price'] = $cp;
                    $response['percent_change_24h'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_24h']);
                    $response['percent_change_7d'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_7d']);
                    $response['percent_change_30d'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_30d']);
                    $response['percent_change_1y'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_change_1y']);
                    $response['high_24h'] = $cp * 1.02;
                    $response['low_24h'] = $cp * 0.98;
                    $response['market_cap'] = cmc_set_default_if_empty($coin['quotes']['USD']['market_cap'], 0);
                    $response['total_volume'] = cmc_set_default_if_empty($coin['quotes']['USD']['volume_24h']);
                    $response['circulating_supply'] = cmc_set_default_if_empty($coin['circulating_supply']);

                    $response['ath'] = cmc_set_default_if_empty($coin['quotes']['USD']['ath_price'], 0);
                    $response['ath_date'] = cmc_set_default_if_empty($coin['quotes']['USD']['ath_date']);
                    $response['ath_change_percentage'] = cmc_set_default_if_empty($coin['quotes']['USD']['percent_from_price_ath'], 0);
                    $response['last_updated'] = gmdate('Y-m-d h:i:s');

                    $coin_data[] = $response;
                    $db_coins[] = cmc_coin_array($coin['id']);

                    $DB = new CMC_Coins();
                    // $DB->create_table();
                    $DB->cmc_insert($coin_data);
                    if (is_array($db_coins) && !empty($db_coins) && $single == false) {
                        $db_coins = $ua_coins_cache == '' ? $db_coins : array_merge($ua_coins_cache, $db_coins);
                        $db_coins = array_unique($db_coins);
                        update_option($ua_coins_name, $db_coins, true);
                        set_transient($ua_refresh_time, date('H:s:i'), $coingecko_api_cache_time * MINUTE_IN_SECONDS);
                    }

                }
            }
            if ($single == true) {
                set_transient('cmc_single_coin' . $required_coins, $coin_data, 10 * MINUTE_IN_SECONDS);
                return $coin_data;
            }

        } // end of ccpwp_update_unavailable_coins_data()

        public static function save_coins_social_info($coin_id)
        {

            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_key = self::get_coingecko_api_key_cmc();
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            $social_data = [];
            $desc_data = [];
            // Do not proceed further if
            if (!cmc_check_required_settings()) {
                return;
            }

            $request = wp_remote_get($url = cmc_get_api_end_point() . 'coins/' . $coin_id . '?' . cmc_get_api_key_end_point() . '=' . $coingecko_api_key, array('timeout' => 120, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);

            $api_data = json_decode($body);

            if (cmc_check_api_errors($api_data)) {
                return self::save_coins_social_info_backup($coin_id);
            }
            //$api_data = library::get_data_through_api($url = cmc_get_api_end_point(). $coin_id, $timeout =120 );
            $storage = array();
            $description = "N/A";
            if (isset($api_data) && $api_data != "") {

                $apiDataID = isset($api_data->id) ? $api_data->id :"";
                $apiDataLinks = isset($api_data->links) ? $api_data->links :"";
                $homepageLinks = (isset($apiDataLinks->homepage) && is_array($apiDataLinks->homepage)) ? $apiDataLinks->homepage : [];
                $storage['coin_id'] = $apiDataID;

              $storage['website'] = !empty($homepageLinks) ? $homepageLinks[0] : 'N/A';
                

                $explorer = isset($apiDataLinks->blockchain_site) ? array_values(
                    array_filter($apiDataLinks->blockchain_site, function ($value) {
                        if ($value != null && $value != '') {
                            return $value;
                        }
                    })
                ) : "";

                $storage['block_explorer'] = $explorer ? $explorer[0] : 'N/A';

                $storage['github'] = (isset($apiDataLinks->repos_url->github) && is_array($apiDataLinks->repos_url->github) && !empty($apiDataLinks->repos_url->github)) ? $apiDataLinks->repos_url->github[0] : 'N/A';
                $storage['twitter'] = !empty($apiDataLinks->twitter_screen_name) ? "https://twitter.com/" . $apiDataLinks->twitter_screen_name : 'N/A';
                $storage['reddit'] = !empty($apiDataLinks->subreddit_url) ? $apiDataLinks->subreddit_url : 'N/A';
                $storage['facebook'] = !empty($apiDataLinks->facebook_username) ? "https://facebook.com/" . $apiDataLinks->facebook_username : 'N/A';

                $description = isset($api_data->description->en) ? preg_replace('~<a\s?+href[^>]+>~', '', $api_data->description->en) : '';
                $description = preg_replace('~</a>~', '', $description);

                $storage['announced'] = !empty($api_data->genesis_date) ? $api_data->genesis_date : 'N/A';

            }
            if (isset($apiDataID)) {
                $social_data[$apiDataID] = array('extra_info' => $storage);
                $desc_data[$apiDataID] = array('description' => $description);
            }
            if (isset($apiDataID) && $storage != null) {
                $DB = new CMC_Coins_Meta();
                $DB->cmc_extra_meta_insert($social_data);
                $DB->cmc_desc_insert($desc_data);
                cmc_track_coingecko_api_hit();
                //socialData::updateOrCreate(array('coin_id' => $coin_id), $storage);
            }

        }

        public static function cmc_save_coins_social_info($coin_id)
        {

            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_key = self::get_coingecko_api_key_cmc();
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            $api_key = (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) ? $api_option['coinmarketcap_api'] : '';
            $social_data = [];
            $desc_data = [];
            // Do not proceed further if
            if (!cmc_check_required_settings()) {
                return;
            }

            $request = wp_remote_get(self::COINMARKETCAP_API_ENDPOINT . 'v2/cryptocurrency/info?CMC_PRO_API_KEY=' . $api_key . '&slug=' . cmc_coin_array_ids($coin_id, true), array('timeout' => 120, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);

            $api_data = json_decode($body, true);

            // if (cmc_check_api_errors($api_data)) {
            //     return self::save_coins_social_info_backup($coin_id);
            // }
            //$api_data = library::get_data_through_api($url = cmc_get_api_end_point(). $coin_id, $timeout =120 );
            $storage = array();
            $description = "N/A";
            if (isset($api_data['data']) && $api_data['data'] != "") {
                foreach ($api_data['data'] as $coin) {
                    $coin_id = cmc_coin_array_ids($coin['slug']);

                    $storage['coin_id'] = $coin_id;
                    $storage['website'] = (is_array($coin['urls']['website']) && !empty($coin['urls']['website'])) ? $coin['urls']['website'][0] : 'N/A';

                    $explorer = $coin['urls']['explorer'] ? array_values(
                        array_filter($coin['urls']['explorer'], function ($value) {
                            if ($value != null && $value != '') {
                                return $value;
                            }
                        })
                    ) : "";

                    $storage['block_explorer'] = $explorer ? $explorer[0] : 'N/A';

                    $storage['github'] = (isset($coin['urls']['source_code']) && is_array($coin['urls']['source_code']) && !empty($coin['urls']['source_code'])) ? $coin['urls']['source_code'][0] : 'N/A';
                    $storage['twitter'] = isset($coin['urls']['twitter'][0]) ? $coin['urls']['twitter'][0] : (($coin_id == "bitcoin") ? 'https://twitter.com/bitcoin' : 'N/A');
                    $storage['reddit'] = isset($coin['urls']['reddit'][0]) ? $coin['urls']['reddit'][0] : 'N/A';
                    $storage['facebook'] = isset($coin['urls']['facebook'][0]) ? $coin['urls']['facebook'][0] : 'N/A';

                    $description = isset($coin['description']) ? preg_replace('~<a\s?+href[^>]+>~', '', $coin['description']) : '';
                    $description = preg_replace('~</a>~', '', $description);
                    $date_format = isset($coin['date_added']) ? new DateTime($coin['date_added']) : '';
                    $storage['announced'] = isset($coin['date_added']) ? $date_format->format('Y-m-d') : 'N/A';

                }
                if (isset($coin_id)) {
                    $social_data[$coin_id] = array('extra_info' => $storage);
                    $desc_data[$coin_id] = array('description' => $description);
                }
                if (isset($coin_id) && $storage != null) {
                    $DB = new CMC_Coins_Meta();
                    $DB->cmc_extra_meta_insert($social_data);
                    $DB->cmc_desc_insert($desc_data);
                    cmc_track_coingecko_api_hit();
                    //socialData::updateOrCreate(array('coin_id' => $coin_id), $storage);
                }
            }

        }
/*
|--------------------------------------------------------------------------
| Backupt API to fetch historical data
|--------------------------------------------------------------------------
 */
        public static function save_coins_social_info_backup($coin_id)
        {

            if (!cmc_coin_array($coin_id, true)) {
                return;
            }

            $request = wp_remote_get($url = self::COINPAPRIKA_API_ENDPOINT . 'coins/' . cmc_coin_array($coin_id, true), array('timeout' => 120, 'sslverify' => true));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $api_data = json_decode($body);

            //$api_data = library::get_data_through_api($url = cmc_get_api_end_point(). $coin_id, $timeout =120 );
            $storage = array();
            $description = "N/A";
            if (isset($api_data) && $api_data != "") {

                $storage['coin_id'] = $coin_id;
                $storage['website'] = (is_array($api_data->links->website) && !empty($api_data->links->website)) ? $api_data->links->website[0] : 'N/A';

                $storage['block_explorer'] = !empty(cmc_get_social_link($api_data->links_extended, "explorer")) ? cmc_get_social_link($api_data->links_extended, "explorer") : 'N/A';

                $storage['github'] = (isset($api_data->links->source_code) && !empty($api_data->links->source_code)) ? $api_data->links->source_code[0] : 'N/A';
                $storage['twitter'] = !empty(cmc_get_social_link($api_data->links_extended, "twitter")) ? cmc_get_social_link($api_data->links_extended, "twitter") : 'N/A';
                $storage['reddit'] = !empty($api_data->links->reddit) ? $api_data->links->reddit[0] : 'N/A';
                $storage['facebook'] = !empty($api_data->links->facebook) ? $api_data->links->facebook[0] : 'N/A';
                $storage['youtube'] = !empty(cmc_get_social_link($api_data->links_extended, "youtube")) ? cmc_get_social_link($api_data->links_extended, "youtube") : 'N/A';

                $description = preg_replace('~<a\s?+href[^>]+>~', '', $api_data->description);
                $description = preg_replace('~</a>~', '', $description);

                $storage['announced'] = !empty($api_data->started_at) ? $api_data->started_at : 'N/A';

            }

            $social_data[$coin_id] = array('extra_info' => $storage);
            $desc_data[$coin_id] = array('description' => $description);
            if ($storage != null) {
                $DB = new CMC_Coins_Meta();
                $DB->cmc_extra_meta_insert($social_data);
                $DB->cmc_desc_insert($desc_data);
                return true;
                //socialData::updateOrCreate(array('coin_id' => $coin_id), $storage);
            }

        }

/*
|--------------------------------------------------------------------------
| USD conversion helper function
|--------------------------------------------------------------------------
 */

        public static function cmc_usd_conversions($currency)
        {
            $conversions = get_transient(self::CMC_USD_CONVERSION);
            $conversions_option = get_option(self::CMC_USD_CONVERSION);
            if (empty($conversions) || $conversions === "" || empty($conversions_option)) {
    
                $request = "";
                $api_option = get_option("openexchange-api-settings");
                $api = (isset($api_option['openexchangerate_api']) && !empty($api_option['openexchangerate_api'])) ? $api_option['openexchangerate_api'] : "";
                if (!empty($api)) {
                    $request = wp_remote_get(self::OPENEXCHANGERATE_API_ENDPOINT . $api . '', array('timeout' => 120, 'sslverify' => true));

                } else {
                    $conversions_option = array('USD' => 1);
                }
                if (is_wp_error($request)) {
                    return false;
                }

                $currency_ids = array("USD", "AUD", "BRL", "CAD", "CZK", "DKK", "EUR", "HKD", "HUF", "ILS", "INR", "JPY", "MYR", "MXN", "NOK", "NZD", "PHP", "PLN", "GBP", "SEK", "VND", "CHF", "TWD", "THB", "TRY", "CNY", "KRW", "RUB", "SGD", "CLP", "IDR", "PKR", "ZAR", "JMD");
                $body = wp_remote_retrieve_body($request);
                $conversion_data = json_decode($body);
                if (isset($conversion_data->rates)) {
                    $conversion_data = (array) $conversion_data->rates;
                } else {
                    $conversion_data = array();
                    if (!empty($conversions_option)) {
                        if ($currency == "all") {

                            return $conversions_option;

                        } else {
                            if (isset($conversions_option[$currency])) {
                                return $conversions_option[$currency];
                            }
                        }
                    }
                }
                if (is_array($conversion_data) && count($conversion_data) > 0) {
                    foreach ($conversion_data as $key => $currency_price) {
                        if (in_array($key, $currency_ids)) {
                            $conversions_option[$key] = $currency_price;
                        }
                    }
                    uksort($conversions_option, function ($key1, $key2) use ($currency_ids) {
                        return (array_search($key1, $currency_ids) > array_search($key2, $currency_ids)) ? 1 : -1;
                    });
                    update_option(self::CMC_USD_CONVERSION, $conversions_option);

                    set_transient(self::CMC_USD_CONVERSION, $conversions_option, self::CMC_USD_CONVERSION_TRANSIENT);
                }
            }

            if ($currency == "all") {

                return $conversions_option;

            } else {
                if (isset($conversions_option[$currency])) {
                    return $conversions_option[$currency];
                }
            }
        }

/*
|--------------------------------------------------------------------------
| Fetching Historical data of mentioned coin
|--------------------------------------------------------------------------
 */
        public static function cmc_historical_coins_arr($coin_id, $day)
        {

            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_key = self::get_coingecko_api_key_cmc();
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;

            // Do not proceed further if
            if (!cmc_check_required_settings()) {
                return;
            }
            $time = ($day == 2) ? "24H" : "365";
            $expiry_time = ($day == 2) ? self::HISTORICAL_24H : self::HISTORICAL_365D;
            $historical_coin_list = get_transient("cmc-" . $coin_id . '-history-data-' . $time);
            $historical_c_list = array();
            if (false == $historical_coin_list || $historical_coin_list === "") {
                $api_url = apply_filters("cmc_alternate_api", cmc_get_api_end_point()) . 'coins/' . $coin_id . '/market_chart?vs_currency=usd&days=' . $day . '&' . cmc_get_api_key_end_point() . '=' . $coingecko_api_key;
                $request = wp_remote_get($api_url, array('timeout' => 120, 'sslverify' => true));
                if (is_wp_error($request)) {
                    return false; // Bail early
                }

                $body = wp_remote_retrieve_body($request);
                $historical_coinsdata = json_decode($body);
                if (cmc_check_api_errors($historical_coinsdata)) {
                    return self::cmc_historical_coins_arr_backup($coin_id, $day);
                }
                if (!empty($historical_coinsdata->error)) {
                    return;
                }
                if (!empty($historical_coinsdata)) {
                    cmc_track_coingecko_api_hit();
                    set_transient("cmc-" . $coin_id . '-history-data-' . $time, date('H:s:i'), $expiry_time);
                    return $historical_coinsdata;

                }
            }

        }

/*
|--------------------------------------------------------------------------
| Backupt API to fetch historical data
|--------------------------------------------------------------------------
 */
        public static function cmc_historical_coins_arr_backup($coin_id, $day)
        {
            if (!cmc_coin_array($coin_id, true)) {
                return;
            }
            $time = ($day == 2) ? "24H" : "365";
            $interval = ($day == 2) ? "1h" : "1d";

            $days = ($day == 2) ? date('Y-m-d', strtotime('now')) : date('Y-m-d', strtotime('-364 day'));
            $expiry_time = ($day == 2) ? self::HISTORICAL_24H : self::HISTORICAL_365D;
            $historical_coin_list = get_transient("cmc-" . $coin_id . '-history-data-' . $time);
            $historical_c_list = array();
            if (false == $historical_coin_list || $historical_coin_list === "") {
                $api_url = self::COINPAPRIKA_API_ENDPOINT . 'tickers/' . cmc_coin_array($coin_id, true) . '/historical?start=' . $days . '&interval=' . $interval;
                $request = wp_remote_get($api_url, array('timeout' => 120, 'sslverify' => true));
                if (is_wp_error($request)) {
                    return false; // Bail early
                }

                $body = wp_remote_retrieve_body($request);
                $historical_coinsdata = json_decode($body, true);
                $customarray = [];
                if (is_array($historical_coinsdata)) {
                    foreach ($historical_coinsdata as $key => $value) {
                        $customarray['prices'][] = array(0 => strtotime($value['timestamp']) * 1000, 1 => $value['price']);
                        $customarray['market_caps'][] = array(0 => strtotime($value['timestamp']) * 1000, 1 => $value['market_cap']);
                        $customarray['total_volumes'][] = array(0 => strtotime($value['timestamp']) * 1000, 1 => $value['volume_24h']);

                    }
                }

                if (!empty($historical_coinsdata->error)) {
                    return;
                }

                if (isset($customarray)) {
                    set_transient("cmc-" . $coin_id . '-history-data-' . $time, date('H:s:i'), $expiry_time);
                    return (object) $customarray;

                }
            }

        }

        public static function cmc_historical_coins_from_cmc_api($coin_id, $day)
        {
            // if (!cmc_coin_array($coin_id, true)) {
            //     return;
            // }
            $time = ($day == 2) ? "24H" : "365";
            $interval = ($day == 2) ? "1h" : "1d";
            $startTime = ($day == 2) ? date('Y-m-d', strtotime('-1 day')) : date('Y-m-d', strtotime('-364 day'));
            $endTime = date('Y-m-d', strtotime('now'));

            $expiry_time = ($day == 2) ? self::HISTORICAL_24H : self::HISTORICAL_365D;
            $historical_coin_list = get_transient("cmc-" . $coin_id . '-history-data-' . $time);
            $DB = new CMC_Coins();
            $coin_ex_data = !empty($coin_id) ? $DB->get_coin_logo($coin_id) : "";
            $api_option = get_option("openexchange-api-settings");
            $api_key = (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) ? $api_option['coinmarketcap_api'] : '';

            if (isset($coin_ex_data['extradata']) && !empty($coin_ex_data['extradata'])) {
                $decode = maybe_unserialize($coin_ex_data['extradata']);

                $historical_c_list = array();
                if (false == $historical_coin_list || $historical_coin_list === "") {
                    $api_url = self::COINMARKETCAP_API_ENDPOINT . "v2/cryptocurrency/quotes/historical?CMC_PRO_API_KEY=$api_key&interval=$interval&time_start=$startTime&time_end=$endTime&id=" . $decode['cmc_id'];
                    $request = wp_remote_get($api_url, array('timeout' => 120, 'sslverify' => true));
                    if (is_wp_error($request)) {
                        return false; // Bail early
                    }

                    $body = wp_remote_retrieve_body($request);
                    $historical_coinsdata = json_decode($body, true);
                    if (isset($historical_coinsdata['status']['error_code']) && $historical_coinsdata['status']['error_code'] == 1006) {
                        return self::cmc_historical_coins_arr($coin_id, $day);
                    }

                    $customarray = [];
                    if (is_array($historical_coinsdata['data'])) {
                        // foreach ($historical_coinsdata['data'] as $first) {
                        foreach ($historical_coinsdata['data']['quotes'] as $key => $value) {
                            $customarray['prices'][] = array(0 => strtotime($value['timestamp']) * 1000, 1 => $value['quote']['USD']['price']);
                            $customarray['market_caps'][] = array(0 => strtotime($value['timestamp']) * 1000, 1 => $value['quote']['USD']['market_cap']);
                            $customarray['total_volumes'][] = array(0 => strtotime($value['timestamp']) * 1000, 1 => $value['quote']['USD']['volume_24h']);

                        }
                        //}
                    }

                    if (!empty($historical_coinsdata->error)) {
                        return;
                    }

                    if (isset($customarray)) {
                        set_transient("cmc-" . $coin_id . '-history-data-' . $time, date('H:s:i'), $expiry_time);
                        return (object) $customarray;

                    }
                }
            }

        }
        /*
        |--------------------------------------------------------------------------
        | Fetching global data
        |--------------------------------------------------------------------------
         */

        public static function cmc_store_global_data()
        {

            $api_option = get_option("openexchange-api-settings");
            $coingecko_api_key = (isset($api_option['coingecko_api'])) ? $api_option['coingecko_api'] : "";
            $coingecko_api_cache_time = isset($api_option['select_cache_time']) ? (int) $api_option['select_cache_time'] : 10;
            // Do not proceed further if
            if (!cmc_check_required_settings()) {
                return;
            }

            //$request = wp_remote_get(apply_filters("cmc_alternate_api", "https://api.coingecko.com/api/v3/global"), array('sslverify' => true));
            $api_url = apply_filters("cmc_alternate_api", cmc_get_api_end_point()) . 'global?' . cmc_get_api_key_end_point() . '=' . $coingecko_api_key;
            $request = wp_remote_get($api_url, array('sslverify' => true, 'timeout' => 120));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $api_response = json_decode($body);
            if (cmc_check_api_errors($api_response)) {
                return self::cmc_store_global_data_backup();
            }
            $response = array();
            if (isset($api_response) && !empty($api_response)) {
                cmc_track_coingecko_api_hit();
                foreach ($api_response->data as $key => $value) {
                    switch ($key) {
                        case 'active_cryptocurrencies':
                            $response['active_cryptocurrencies'] = $value;
                            break;
                        case 'markets':
                            $response['markets'] = $value;
                            break;
                        case 'total_market_cap':
                            $response['total_market_cap'] = $value->usd;
                            break;
                        case 'total_volume':
                            $response['total_volume'] = $value->usd;
                            break;
                        case 'market_cap_percentage':
                            $response['market_cap_percentage'] = (object) array('btc' => number_format($value->btc, '2', '.', ''),
                                'eth' => number_format($value->eth, '2', '.', ''));
                    }
                }
            }
            return (object) $response;

        }

        public static function cmc_store_global_data_backup()
        {

            $api_url = self::COINPAPRIKA_API_ENDPOINT . 'global';
            $request = wp_remote_get($api_url, array('sslverify' => true, 'timeout' => 120));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $api_response = json_decode($body, true);
            $response = array();
            if (isset($api_response) && !empty($api_response)) {

                $response['active_cryptocurrencies'] = $api_response['cryptocurrencies_number'];

                $response['total_market_cap'] = $api_response['market_cap_usd'];

                $response['total_volume'] = $api_response['volume_24h_usd'];

                $response['market_cap_percentage'] = (object) array('btc' => number_format($api_response['bitcoin_dominance_percentage'], '2', '.', ''));

            }
            return (object) $response;

        }

        public static function cmc_store_global_data_from_cmc_api()
        {
            $api_option = get_option("openexchange-api-settings");
            $api_key = (isset($api_option['coinmarketcap_api']) && !empty($api_option['coinmarketcap_api'])) ? $api_option['coinmarketcap_api'] : '';

            $api_url = self::COINMARKETCAP_API_ENDPOINT . 'v1/global-metrics/quotes/latest?CMC_PRO_API_KEY=' . $api_key;
            $request = wp_remote_get($api_url, array('sslverify' => true, 'timeout' => 120));
            if (is_wp_error($request)) {
                return false; // Bail early
            }

            $body = wp_remote_retrieve_body($request);
            $api_response = json_decode($body, true);
            $response = array();
            if (isset($api_response['data']) && !empty($api_response['data'])) {

                $response['active_cryptocurrencies'] = $api_response['data']['active_cryptocurrencies'];
                $response['total_market_cap'] = $api_response['data']['quote']['USD']['total_market_cap'];

                $response['total_volume'] = $api_response['data']['quote']['USD']['total_volume_24h'];

                $response['market_cap_percentage'] = (object) array('btc' => number_format($api_response['data']['btc_dominance'], '2', '.', ''), 'eth' => number_format($api_response['data']['eth_dominance'], '2', '.', ''));

            }
            return (object) $response;

        }

         /**
         * Check if a string contains emoji.
         *
         * @param string $string The string to check.
         * @return bool True if the string contains emoji, false otherwise.
         */
        public static function contains_emoji($string)
        {
            return preg_match('/[\x{1F600}-\x{1F64F}\x{1F300}-\x{1F5FF}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}]/u', $string) > 0;
        }


    }
}
